import com.arcadedb.database.Database;
import com.arcadedb.database.DatabaseFactory;
import com.arcadedb.graph.Vertex;
import com.arcadedb.query.sql.executor.ResultSet;
import com.mysql.cj.log.Log;
import indi.hjhk.csv.CSVReader;
import indi.hjhk.log.Logger;
import nju.hjh.arcadedb.timeseries.*;
import nju.hjh.arcadedb.timeseries.datapoint.DataPoint;
import nju.hjh.arcadedb.timeseries.datapoint.StringDataPoint;
import nju.hjh.arcadedb.timeseries.exception.TimeseriesException;
import nju.hjh.arcadedb.timeseries.statistics.Statistics;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

public class CarPeriodQueryTest {
    public static void main(String[] args) throws TimeseriesException, IOException, CSVReader.CSVFormatException {
        Logger logger = Logger.getPureLogger("CarPeriod");

        DatabaseFactory dbf = new DatabaseFactory("./databases/carTsTest5Debug");
        Database database;
        if (!dbf.exists()) {
            database = dbf.create();
        } else {
            database = dbf.open();
        }

        final String vertexType = "car";

        ArrayList<String> csvFiles = new ArrayList<>();
        csvFiles.add("./csv/1101.csv");
        csvFiles.add("./csv/1102.csv");
        csvFiles.add("./csv/1103.csv");
        csvFiles.add("./csv/1104.csv");
        csvFiles.add("./csv/1105.csv");

        Random ran = new Random();
        TimeseriesEngine tsEngine = new TimeseriesEngine(database);

        for (int i = 0; i < 20; i++){
            int carOffset = ran.nextInt(1000000);
            long startTime = System.currentTimeMillis(), queryCarTime, queryPassidTime;

            String sql = String.format("select from %s where carId='辽LYE107_0' limit 1", vertexType);
            ResultSet rs = database.query("SQL", sql);

            if (rs.hasNext()){
                Vertex car = rs.next().getVertex().orElseGet(() -> null);
                if (car != null){
                    queryCarTime = System.currentTimeMillis() - startTime;
                    String carId = car.getString("carId");
                    logger.logOnStdout("querying car with carId %s", carId);
                    startTime = System.currentTimeMillis();

                    Statistics passIdStats = tsEngine.aggregativeQuery(car, "passId", 0, Long.MAX_VALUE);
                    logger.logOnStdout("total statistics on pass id: %s", passIdStats.toPrettyPrintString());

                    logger.logOnStdout("time series content check start:");
                    DataPointSet passIdSet = tsEngine.periodQuery(car, "passId", 0, Long.MAX_VALUE);
                    DataPointSet stationIdSet = tsEngine.periodQuery(car, "stationId", 0, Long.MAX_VALUE);
                    DataPoint dpPassId, dpStationId;
                    int tsCount = 0;
                    while ((dpPassId = passIdSet.next()) != null){
                        dpStationId = stationIdSet.next();
                        if (dpStationId == null){
                            logger.logOnStderr("station id not found while pass id exists");
                            break;
                        }
                        if (dpPassId.timestamp != dpStationId.timestamp){
                            logger.logOnStderr("timestamp not match between pass id ans station id");
                            break;
                        }
                        if (dpPassId instanceof StringDataPoint strDPPassId && dpStationId instanceof StringDataPoint strDPStationId) {
                            logger.logOnStdout("\ttimestamp=%d, passId=%s, stationId= %s", strDPPassId.timestamp, strDPPassId.value, strDPStationId.value);
                            tsCount++;
                        }
                        else{
                            logger.logOnStderr("result is not string data point, continue");
                            break;
                        }
                    }
                    if (stationIdSet.next() != null)
                        logger.logOnStderr("pass id not found while station id exists");
                    queryPassidTime = System.currentTimeMillis() - startTime;
                    logger.logOnStdout("query finished, count=%d, timeSpent: carVertex: %dms + timeseries: %dms = %dms", tsCount, queryCarTime, queryPassidTime, queryCarTime+queryPassidTime);
                    logger.logOnStdout("csv check start");
                    int csvCount = 0;
                    long prevTimestamp = -1;
                    for(String csvFileName : csvFiles){
                        CSVReader reader = new CSVReader(csvFileName);
                        reader.readHeader();
                        while (reader.next()){
                            String csvCarId = reader.getString("VLP") + "_" + reader.getString("VLPC");
                            if (carId.equals(csvCarId)){
                                long curTimestamp = reader.getLong("TIME");
                                if (curTimestamp > prevTimestamp){
                                    csvCount++;
                                    prevTimestamp = curTimestamp;
                                    logger.logOnStdout("\tnew timestamp: %d", curTimestamp);
                                }
                            }
                        }
                    }
                    logger.logOnStdout("csv query finished, count=%d", csvCount);
                    logger.logOnStdout("check statistics == time series == csv: %s", passIdStats.count == tsCount && tsCount == csvCount);
                }
            }
        }

        database.close();
    }
}
